Angular Lists
Lists template-ல் items-ன் collections-ஐ display செய்கின்றன.
List Rendering Essentials
- Loop: Stable identity-க்கு track உடன் @if பயன்படுத்தவும் மற்றும் empty states-க்கு @empty பயன்படுத்தவும்.
- Signals: List state-ஐ signal-ல் store செய்யவும் (e.g., items = signal([...])) மற்றும் immutably update செய்யவும் set()/update() உடன்.
- Identity: Unnecessary DOM work avoid செய்ய stable key மூலம் track செய்யவும் (e.g., it.id).
- Derived views: UI-க்கு உங்கள் data-ன் copies-ஐ filter/sort செய்யவும்; source list intact-காக வைக்கவும் (derived state-க்கு computed() பயன்படுத்தவும்).
Basic List Syntax
<ul>
@for (item of items(); let i = $index; track item) {
<li>{{ i + 1 }}. {{ item }}</li>
} @empty {
<li>No items</li>
}
</ul>
Note
Control Flow for @for, Conditional Rendering, and Templates for interpolation and basics ஆகியவற்றை காணவும்.
Basic Lists
Loop செய்ய @if பயன்படுத்தவும்; let i = $index உடன் index-ஐ expose செய்யவும்.
Signals உடன் immutably update செய்யவும் (e.g., items.update(arr => [...arr, newItem])).
Basic List Example
<ul>
@for (item of items(); let i = $index; track item) {
<li>{{ i + 1 }}. {{ item }}</li>
} @empty {
<li>No items</li>
}
</ul>
Example
@if உடன் basic list render செய்யவும் மற்றும் index-ஐ expose செய்யவும்:
Basic Lists Example
import { bootstrapApplication } from '@angular/platform-browser';
import { Component, signal } from '@angular/core';
@Component({
selector: 'app-root',
standalone: true,
template: `
<h3>Lists</h3>
<ul>
@for (item of items(); let i = $index; track item) {
<li>{{ i + 1 }}. {{ item }}</li>
} @empty {
<li>No items</li>
}
</ul>
<button (click)="add()">Add Item</button>
<button (click)="clear()">Clear</button>
<button (click)="reset()">Reset</button>
`
})
export class App {
items = signal(['Angular', 'React', 'Vue']);
add() { this.items.update(arr => [...arr, 'Svelte']); }
clear() { this.items.set([]); }
reset() { this.items.set(['Angular', 'React', 'Vue']); }
}
bootstrapApplication(App);
Example Explained
- @for (item of items(); let i = $index; track item): items signal-ல் loops செய்கிறது; zero-based index-ஐ i ஆக expose செய்கிறது; primitive item-ஐ identity-காக பயன்படுத்துகிறது.
- Buttons: add() immutably append செய்கிறது, clear() empty list-ஐ set செய்கிறது, reset() defaults-ஐ restore செய்கிறது.
- @empty: Items இல்லாத போது fallback list item-ஐ render செய்கிறது.
Notes
- No import needed: @if Angular-ன் template syntax-ல் built-in ஆகும்; module import தேவையில்லை.
- Don't mutate in place: Signals உடன், updates trigger செய்ய new array assign செய்ய set()/update()-ஐ விரும்பவும்.
Lists with track (@for)
List changes-ல், Angular DOM rows-ஐ data items உடன் reconcile செய்கிறது.
track stable identity வழங்குகிறது (e.g., an id) DOM churn minimize செய்ய மற்றும் focus/inputs preserve செய்ய.
Legacy equivalence: *ngFor உடன், அதே effect achieve செய்ய trackBy பயன்படுத்தவும்.
Track Example Syntax
@for (it of items(); track it.id) { <li>{{ it.name }}</li> } @empty { <li>No items</li> }
Example
Track பயன்படுத்தி stable identity உடன் lists render செய்யவும்:
Lists with track Example
import { bootstrapApplication } from '@angular/platform-browser';
import { Component, signal } from '@angular/core';
type Item = { id: number; name: string };
@Component({
selector: 'app-root',
standalone: true,
template: `
<h3>Lists with track</h3>
<ul>
@for (it of items(); let i = $index; track it.id) {
<li>{{ i + 1 }}. {{ it.name }} (id: {{ it.id }})</li>
}
</ul>
<button (click)="renameFirst()">Rename first</button>
<button (click)="shuffle()">Shuffle</button>
<button (click)="add()">Add item</button>
`
})
export class App {
items = signal([
{ id: 1, name: 'Angular' },
{ id: 2, name: 'React' },
{ id: 3, name: 'Vue' }
]);
nextId = 4;
renameFirst() {
this.items.update(arr => arr.map((it, i) => i === 0 ? { ...it, name: it.name + ' *' } : it));
}
shuffle() {
this.items.update(arr => {
const copy = [...arr];
for (let i = copy.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[copy[i], copy[j]] = [copy[j], copy[i]];
}
return copy;
});
}
add() {
this.items.update(arr => [...arr, { id: this.nextId++, name: 'New ' + Date.now() }]);
}
}
bootstrapApplication(App);
Example Explained
- track it.id: Stable identity வழங்குகிறது அதனால் items shuffle அல்லது update ஆகும் போது Angular DOM rows reuse செய்கிறது, focus மற்றும் local state preserve செய்கிறது.
- renameFirst(): First item-ன் name-ஐ immutably update செய்கிறது (new object reference) change detection trigger செய்ய.
- shuffle(): Track உடன் DOM reuse demonstrate செய்ய order-ஐ randomize செய்கிறது.
- add(): Unique id உடன் new item-ஐ append செய்கிறது.
Notes
- Avoid index identity: Order மாறக்கூடியால் array index-ஐ identity-காக பயன்படுத்தாதீர்கள்; stable id பயன்படுத்தவும்.
- Ensure uniqueness: Duplicate id values DOM/UI desync cause செய்யும். Unique keys பயன்படுத்தவும்.
- *ngFor equivalence: *ngFor உடன், அதே behavior achieve செய்ய trackBy பயன்படுத்தவும்.
Filter & Sort
Signals-அடிப்படையில் computed() உடன் derived view compute செய்யவும்.
உங்கள் data-ன் copies-ஐ filter மற்றும் sort செய்யவும்; easy resets-க்கு source list intact-காக வைக்கவும்.
Filter & Sort Example
import { signal, computed } from '@angular/core';
items = signal([{ name: 'Angular', price: 0 }, { name: 'React', price: 0 }]);
query = signal('');
sortKey = signal<'name' | 'price'>('name');
sortDir = signal<1 | -1>(1);
view = computed(() => {
const q = query().toLowerCase();
const dir = sortDir();
const key = sortKey();
return items()
.filter(it => it.name.toLowerCase().includes(q))
.sort((a, b) => {
const av: any = (a as any)[key];
const bv: any = (b as any)[key];
return av < bv ? -1 * dir : av > bv ? 1 * dir : 0;
});
});
@for (p of view(); track p.name) {
<tr>
<td>{{ p.name }}</td>
<td>{{ p.price | currency:'USD' }}</td>
</tr>
}
Example
computed() பயன்படுத்தி lists filter மற்றும் sort செய்யவும்:
Filter & Sort Example
import { bootstrapApplication } from '@angular/platform-browser';
import { Component, signal, computed } from '@angular/core';
import { CommonModule } from '@angular/common';
type Product = { name: string; price: number };
@Component({
selector: 'app-root',
standalone: true,
imports: [CommonModule],
template: `
<h3>Filter & Sort</h3>
<div style="display:flex;gap:8px;margin-bottom:8px;">
<label>Search: <input #q (input)="query.set(q.value)" placeholder="Type to filter..." /></label>
<button (click)="setSort('name')">Sort by Name</button>
<button (click)="setSort('price')">Sort by Price</button>
<button (click)="toggleDir()">{{ sortDir() === 1 ? 'Asc' : 'Desc' }}</button>
</div>
<table style="width:100%;border-collapse:collapse;">
<thead>
<tr><th style="border:1px solid #ddd;padding:8px;background:#f7f7f7;">Name</th><th style="border:1px solid #ddd;padding:8px;background:#f7f7f7;width:140px;">Price</th></tr>
</thead>
<tbody>
@for (p of view(); track p.name) {
<tr>
<td style="border:1px solid #ddd;padding:8px;">{{ p.name }}</td>
<td style="border:1px solid #ddd;padding:8px;">{{ p.price | currency:'USD' }}</td>
</tr>
}
</tbody>
</table>
`
})
export class App {
items = signal<Product[]>([
{ name: 'Angular', price: 0 },
{ name: 'React', price: 0 },
{ name: 'Vue', price: 0 },
{ name: 'Svelte', price: 0 },
{ name: 'Solid', price: 0 },
{ name: 'Lit', price: 0 }
]);
query = signal('');
sortKey = signal<'name' | 'price'>('name');
sortDir = signal<1 | -1>(1); // 1 asc, -1 desc
view = computed(() => {
const q = this.query().toLowerCase();
const dir = this.sortDir();
const key = this.sortKey();
return this.items()
.filter(it => it.name.toLowerCase().includes(q))
.sort((a, b) => {
const av: any = (a as any)[key];
const bv: any = (b as any)[key];
return av < bv ? -1 * dir : av > bv ? 1 * dir : 0;
});
});
setSort(key: 'name' | 'price') {
if (this.sortKey() === key) {
this.toggleDir();
} else {
this.sortKey.set(key);
}
}
toggleDir() {
this.sortDir.set(this.sortDir() === 1 ? -1 : 1);
}
}
bootstrapApplication(App);
Example Explained
- computed() view: Signals-லிருந்து source list mutate செய்யாமல் filtered/sorted array derive செய்கிறது.
- query/sortKey/sortDir: UI-லிருந்து இந்த signals update செய்வதன் மூலம் derived view-ஐ control செய்கிறது.
- @for (p of view(); track p.name): Derived rows-ஐ render செய்கிறது; identity-க்கு stable key (p.name) பயன்படுத்துகிறது.
Note
Templates-ல் heavy work avoid செய்யவும்; computed() உடன் pre-compute செய்யவும் மற்றும் templates fast-காக வைக்க @if உடன் loop செய்யவும்.